

#ifndef UD_DIMASSOC_H
#define UD_DIMASSOC_H

class UcDbPointRef;
class UcDbLeader;
class UcDbMLeader;

class UcDbDimAssoc : public UcDbObject
{
public:
    UCRX_DECLARE_MEMBERS(UcDbDimAssoc);

    enum { kMaxPointRefs = 4 };

    enum PointType {
		kXline1Point      = 0,
		kXline2Point      = 1,
		kOriginPoint      = 0,
		kDefiningPoint    = 1,
		kXline1Start      = 0,
		kXline1End        = 1,
		kXline2Start      = 2,
		kXline2End        = 3,
		kVertexPoint      = 2,
		kChordPoint       = 0,
		kCenterPoint      = 1,
		kFarChordPoint    = 1,
		kOverrideCenterPoint   = 2,
		kAngLineStart     = 2,
		kJogPoint         = 3,
    	kAngLineEnd       = 3,
		kLeaderPoint      = 0
	};

    enum AssocFlags {
        kFirstPointRef     = 1,
        kSecondPointRef    = 2,
        kThirdPointRef     = 4,
        kFourthPointRef    = 8
    };

    enum RotatedDimType {
        kUnknown       = 0,
        kParallel      = 1,
        kPerpendicular = 2
    };

	UcDbDimAssoc();
	virtual ~UcDbDimAssoc();
	UcDbObjectId dimObjId() const;
	Ucad::ErrorStatus setDimObjId(const UcDbObjectId& dimId);
	Ucad::ErrorStatus setAssocFlag(int ptType, bool value);
	void setAssocFlag(int assocFlg);
	bool assocFlag(int ptType) const;
	int assocFlag(void);
	Ucad::ErrorStatus setPointRef(int ptType, UcDbPointRef* ptRef);
	const UcDbPointRef *pointRef(int ptType) const;
	Ucad::ErrorStatus setRotatedDimType(RotatedDimType dimType);
	RotatedDimType    rotatedDimType() const;
	Ucad::ErrorStatus addToPointRefReactor();
	Ucad::ErrorStatus addToDimensionReactor(bool isAdd = true);
	Ucad::ErrorStatus removePointRef(int ptType);
	Ucad::ErrorStatus updateDimension(bool update = true, bool skipReactors = false);
	Ucad::ErrorStatus removeAssociativity(bool force = true);
	bool              isTransSpatial() const;
	Ucad::ErrorStatus setTransSpatial(bool value);
	Ucad::ErrorStatus startCmdWatcher();

	Ucad::ErrorStatus startOopsWatcher(bool bAddAll = true);
	void              removeOopsWatcher(void);
	Ucad::ErrorStatus restoreAssocFromOopsWatcher(void);
	bool              hasOopsWatcher(void) const;
	Ucad::ErrorStatus post(UcDbObjectId dimId, 
							UcDbObjectId& dimAssocId, 
							bool isActive = true);
	Ucad::ErrorStatus getDimAssocGeomIds(UcDbObjectIdArray& geomIds) const;
	bool              isAllGeomErased() const;

	virtual Ucad::ErrorStatus dwgInFields(UcDbDwgFiler*);
	virtual Ucad::ErrorStatus dwgOutFields(UcDbDwgFiler*) const;
	virtual Ucad::ErrorStatus dxfInFields(UcDbDxfFiler*);
	virtual Ucad::ErrorStatus dxfOutFields(UcDbDxfFiler*) const;
	virtual void modifiedGraphics(const UcDbEntity* pObj);

	virtual Ucad::ErrorStatus swapReferences (const UcDbIdMapping& idMap);


	Ucad::ErrorStatus updateFillet(const UcDbObjectIdArray& ids);
	Ucad::ErrorStatus updateAssociativity(const UcDbObjectIdArray& ids);
	Ucad::ErrorStatus updateXrefSubentPath();
	Ucad::ErrorStatus updateSubentPath(UcDbIdMapping& idMap);
	void updateDueToMirror(bool wasInMirror);

protected:
	Ucad::ErrorStatus   setPointRefReactor  (int ptType, 
											 bool isAdd = true);
	Ucad::ErrorStatus   removeDimExtDict    (void);
	bool                isPointBetweenRays  (const UcGePoint3d& vertex, 
											 const UcGePoint3d& firstPt, 
											 const UcGePoint3d& secondPt, 
											 const UcGePoint3d& angPt,
											 const UcGeVector3d& normal);
	Ucad::ErrorStatus   updateDimension     (UcDbRotatedDimension* pRotDim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbAlignedDimension* pAlnDim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbRadialDimension* pRadDim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbRadialDimensionLarge* pRadDimLarge, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbDiametricDimension* pDiaDim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDb2LineAngularDimension* pA2Dim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDb3PointAngularDimension* pA3Dim,
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbOrdinateDimension* pOrdDim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbArcDimension* pArcDim, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbLeader* pLeader, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimension     (UcDbMLeader* pMLeader, 
											 UcGePoint3d* pNewPts, 
											 bool bUpdate = true);
	Ucad::ErrorStatus   updateDimLineAndTextLocation(UcDbRotatedDimension* pAlnDim, 
											 const UcGePoint3d* kpOldPts, 
											 const UcGePoint3d* kpNewPts);
	Ucad::ErrorStatus   updateDimLineAndTextLocation(UcDbAlignedDimension* pAlnDim, 
											 const UcGePoint3d* pOldPts, 
											 const UcGePoint3d* pNewPts);
	Ucad::ErrorStatus   updateDimLineAndTextLocation(UcDb2LineAngularDimension* pA2Dim, 
											 const UcGePoint3d* pOldPts, 
											 const UcGePoint3d* pNewPts);
	Ucad::ErrorStatus   updateDimLineAndTextLocation(UcDb3PointAngularDimension* pA3Dim, 
											 const UcGePoint3d* pOldPts, 
											 const UcGePoint3d* pNewPts);
	Ucad::ErrorStatus   updateDimLineAndTextLocation(UcDbArcDimension* pArcDim, 
											 const UcGePoint3d* kpOldPts, 
											 const UcGePoint3d* kpNewPts);
	Ucad::ErrorStatus   calculate3PointAngDimArcLocation(const UcGePoint3d* kpOldPts, 
											 const UcGePoint3d& kOldArcPt, 
											 const UcGePoint3d& kOldTextPt, 
											 const UcGePoint3d* kpNewPts, 
											 const UcGeVector3d& normal, 
											 UcGePoint3d& newArcPt, 
											 UcGePoint3d& newTextPt);
	Ucad::ErrorStatus   calculate2LineAngDimArcLocation(const UcGePoint3d* kpOldPts, 
											 const UcGePoint3d& kOldArcPt, 
											 const UcGePoint3d& kOldTextPt, 
											 const UcGePoint3d* kpNewPts, 
											 const UcGeVector3d& kNormal, 
											 UcGePoint3d& newArcPt, 
											 UcGePoint3d& newTextPt);


};


Ucad::ErrorStatus
ucdbPostDimAssoc(UcDbObjectId dimId, UcDbDimAssoc* pDimAssoc, 
				 UcDbObjectId& dimAssocId, bool isActive = true);

Ucad::ErrorStatus
ucdbUpdateDimension(UcDbObjectId dimId);

 
Ucad::ErrorStatus
ucdbUpdateAllDimensions(UcDbDatabase* pDb);


Ucad::ErrorStatus
ucdbGetDimAssocId(UcDbObjectId dimId, UcDbObjectId& dimAssocId);


Ucad::ErrorStatus
ucdbGetDimAssocIds(UcDbObjectId entId, UcDbObjectIdArray& dimAssocIds);


bool
ucdbIsTransSpatial(const UcDbFullSubentPath& idPath);

#endif  //  UD_DBDIMASSOC_H
